package cn.hg.jbsa.admin.interceptor;

import java.util.List;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.ActionException;
import com.jfinal.log.Log;

import cn.hg.jboot.core.constant.BaseConstants;
import cn.hg.jboot.core.exception.BaseServiceException;
import cn.hg.jboot.core.vo.BaseResponseVo;
import cn.hg.jbsa.admin.controller.BaseJbsaAdminController;
import cn.hg.jbsa.admin.model.JbsaAdmin;
import cn.hg.jbsa.admin.model.JbsaDict;
import cn.hg.jbsa.common.web.LayuiDtree;
import cn.hg.jbsa.common.web.LayuiPage;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import io.jboot.aop.annotation.ConfigValue;
import io.jboot.utils.RequestUtil;

/**
 * @author 胡高
 * @date 2021/12/23
 */
public class JbsaAuthInterceptor implements Interceptor {
    private static final Log LOG = Log.getLog(JbsaAuthInterceptor.class);

    private static final List<String> NO_AUTH_ACTIONS =
        CollUtil.toList(new String[] {"/admin/login", "/admin/doLogin", "/admin/doLogout", "/admin/captcha"});

    private static final List<String> LOGIN_REDIRCT_ACTIONS =
        CollUtil.toList(new String[] {"/admin", "/admin/index", "/admin/logout"});

    private static final String LOGIN_ACTION = "/admin/login";

    private static final String TIMEOUT_PAGE = "/admin/error/timeout.html";

    @ConfigValue("jbsa.env.mode")
    private String envMode;

    @ConfigValue("jbsa.server.region.code")
    private String regionCode;

    @ConfigValue("jbsa.server.region.name")
    private String regionName;

    /* (non-Javadoc)
     * @see com.jfinal.aop.Interceptor#intercept(com.jfinal.aop.Invocation)
     */
    @Override
    public void intercept(Invocation inv) {
        // 设置环境变量
        inv.getController().setAttr("jbsaAppMode", this.envMode);
        inv.getController().setAttr("jbsaRegionCode", this.regionCode);
        inv.getController().setAttr("jbsaRegionName", this.regionName);

        /*
         * 必须继承自BasePartnerController
         */
        if (!(inv.getController() instanceof BaseJbsaAdminController)) {
            if (RequestUtil.isAjaxRequest(inv.getController().getRequest())) {
                // 返回错误Json
                this.returnJson(inv, BaseConstants.RETURN_CODE_VALUE_FAILED, "Controller必须由BaseJbsaAdminController继承");
                return;
            } else {
                // 跳转到错误页面
                inv.getController().renderError(HttpStatus.HTTP_INTERNAL_ERROR);
                return;
            }
        }

        BaseJbsaAdminController adminController = (BaseJbsaAdminController)inv.getController();

        /*
         * 从Session中取得当前管理实例
         */
        JbsaAdmin admin = adminController.getCurrentAdmin();

        String action = inv.getActionKey();
        if (ObjectUtil.isNull(admin) && !CollUtil.contains(NO_AUTH_ACTIONS, action)) {
            /*
             * 如果Session中不存在登录信息
             */
            if (RequestUtil.isAjaxRequest(adminController.getRequest())) { // 如果是Ajax请求
                this.returnJson(inv, BaseConstants.RETURN_CODE_VALUE_FAILED, "登录超时，请重新登录！");
                return;
            } else {
                if (CollUtil.contains(LOGIN_REDIRCT_ACTIONS, action)) {
                    adminController.redirect(LOGIN_ACTION);
                } else {
                    adminController.render(TIMEOUT_PAGE);
                }
            }
        } else {
            try {
                /*
                 * 执行
                 */
                inv.invoke();
            } catch (BaseServiceException e) {
                LOG.warn("服务异常：code={}, message={}", e.getCode(), e.getMessage(), e);
                // 捕获服务异常
                if (RequestUtil.isAjaxRequest(inv.getController().getRequest())) {
                    this.returnJson(inv, e.getCode(), e.getMessage());
                }
                return;
            } catch (ActionException e) {
                if (e.getErrorCode() == HttpStatus.HTTP_FORBIDDEN) {
                    if (RequestUtil.isAjaxRequest(inv.getController().getRequest())) {
                        this.returnJson(inv, BaseConstants.RETURN_CODE_VALUE_FAILED, "您没有此操作的权限！");
                    }
                }
            } catch (Throwable e) {
                // 捕获所有其它异常
                LOG.error("系统异常", e);
                if (RequestUtil.isAjaxRequest(inv.getController().getRequest())) {
                    this.returnJson(inv, BaseConstants.RETURN_CODE_VALUE_FAILED, "系统异常");
                }
                return;
            }
        }
    }

    private void returnJson(Invocation inv, int code, String message) {
        String method = inv.getMethodName();
        if (CharSequenceUtil.equals(method, "list")) {
            inv.getController().renderJson(new LayuiPage(message));
        } else if (CharSequenceUtil.equals(method, "tree")) {
            inv.getController().renderJson(new LayuiPage(message));
        } else if (CharSequenceUtil.equals(method, "dtree")) {
            inv.getController().renderJson(new LayuiDtree<JbsaDict>(code, message));
        } else {
            inv.getController().renderJson(BaseResponseVo.fail(code, message));
        }
    }

}
